package com.changgou.util;

import org.apache.commons.lang.StringUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

public class MD5Utils {


        /**
         * 编码
         * @param bytes
         * @return
         */
        public static String encode(byte[] bytes){
            return new BASE64Encoder().encode(bytes);
        }

        /**
         * 解码
         * @param str
         * @return
         */
        public static String decode(String str){
            try {
                byte[] bytes = new BASE64Decoder().decodeBuffer(str);
                return new String(bytes);
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }

        /**
         * 生成盐(无参)
         * @return
         */
        public static String getSalt(){
            //默认id给10
            return getSalt(10);
        }

        /**
         * 生成盐(带参)
         *
         * @param
         */
        public static String getSalt(int id){
            if(id<20&&id>3){
                String uuid=null;
                uuid = UUID.randomUUID().toString().replace("-", "");

                //拼接一个专属前缀进行判断盐的合法性
                StringBuilder sb=new StringBuilder();
                sb.append("$yqs$");
                if (id<10){
                    sb.append("0");
                }
                sb.append(id);

                sb.append("$");
                //取UUID前10
                String bytesUuid = encode(uuid.substring(0,10).getBytes());
                sb.append(bytesUuid);

                return sb.toString();
            }else {
                throw new IllegalArgumentException("参数不在规定范围内");
            }

        }

        /**
         * 生成密文
         * @param password
         * @param salt
         * @return
         */
        public static String getEncryptPw(String password, String salt){

            int off=5;
            StringBuilder sb=new StringBuilder();
            if (salt==null){
                throw new IllegalArgumentException("盐不能为空");
            }else{
                int saltLength=salt.length();
                if (saltLength<23){
                    throw new IllegalArgumentException("非法盐");
                }else if (salt.startsWith("$yqs$")){
                    sb.append("$yqs$");
                    if (salt.charAt(5)=='0'){//第五位是0的话,只有23位
                        String real_salt=salt.substring(off+2,22);
                        sb.append("0");
                        sb.append(real_salt);
                    }else {
                        sb.append("1").append(salt.charAt(6)).append("$");
                        String real_salt=salt.substring(off+3,22);
                        sb.append(real_salt);
                    }
                    try {
                        MessageDigest md5 = MessageDigest.getInstance("MD5");
                        byte[] bytes = md5.digest(password.getBytes("UTF-8"));
                        String encode = encode(bytes);
                        sb.append(encode);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            }
            return sb.toString();
        }

        /**
         * 比较密码
         * @param password
         * @param encryptPw
         * @return
         */
        public static boolean checkPw(String password,String encryptPw){
            if (StringUtils.isEmpty(password)){
                return false;
            }
            int id=10;
            //
            if (encryptPw.startsWith("$yqs$")) {
                if (encryptPw.charAt(5)=='0'){
                    //4-9
                    id=9;
                }else {
                    //10-19
                    id=Integer.parseInt(encryptPw.substring(5,7));
                }
            }
            String encryptPw1 = getEncryptPw(password, getSalt(id));
            //比较
            if (encryptPw.length()!=encryptPw1.length()){
                //长度不同,密码错误
                return false;
            }else {
                if (id<10){
                    String decode = decode(encryptPw.substring(21));
                    String decode1 = decode(encryptPw1.substring(21));
                    return decode.equals(decode1);
                }else {
                    return encryptPw.substring(22).equals(encryptPw1.substring(22));
                }
            }
        }






        public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException {

            //$yqs$10$MDRmZmFjNDdkZggnzLDuqKcGxMNKFokfhOew==是12345的密码

            boolean b = checkPw("12345", "$yqs$10$MDRmZmFjNDdkZggnzLDuqKcGxMNKFokfhOew==");
            System.out.println(b);
        }
    }


